package com.hj.ct.logic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.content.ContentValues;
import android.os.Handler;
import android.os.Looper;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hj.ct.App;
import com.hj.ct.db.dao.DeviceDao;
import com.hj.ct.db.dao.GatherDataDao;
import com.hj.ct.http.StringHttpResponseListener;
import com.hj.ct.model.CompositeData;
import com.hj.ct.model.SetAlarm;
import com.hj.ct.parse.Device;
import com.hj.ct.parse.GatherData;
import com.hj.ct.parse.Report1Data;
import com.hj.ct.parse.Report2Data;
import com.hj.ct.parse.Report3Data;
import com.hj.ct.util.LogF;
import com.hj.ct.util.SetAlarmUtil;

public class GatherDataLogic extends BaseLogic {
	private String TAG = GatherDataLogic.class.getSimpleName();
	private GatherDataDao gatherDataDao;
	private DeviceDao deviceDao;
	private static GatherDataLogic realDataLogic;

	private GatherDataLogic() {
		gatherDataDao = new GatherDataDao(App.getContext());
		deviceDao = new DeviceDao(App.getContext());
	}

	public static GatherDataLogic getInstance() {
		if (realDataLogic == null) {
			realDataLogic = new GatherDataLogic();
		}
		return realDataLogic;
	}

	private OnHandlerResponse realDataHandler;

	public void setRealDataHandler(OnHandlerResponse handler) {
		realDataHandler = handler;
		getRealData();
	}

	private void handerRealDataResponse(int action, int code, Object... obj) {
		if (realDataHandler != null) {
			realDataHandler.handlerResponse(action, code, obj);
		}
	}

	public void getRealData() {

		httpUtil.get(HttpCommon.REAL_DATA, new StringHttpResponseListener() {

			@Override
			public void onFailure(int statusCode, String content, Throwable error) {
				// TODO Auto-generated method stub
				LogF.d(TAG, "getRealData statusCode:" + statusCode + ",content:" + content);
				handerRealDataResponse(LogicActions.REAL_DATA_ERROR, statusCode, content);
			}

			@Override
			public void onSuccess(int statusCode, String content) {
				LogF.d(TAG, "getRealData statusCode:" + statusCode + ",content:" + content);
				// 成功statusCode:200, 登录超时 statuscode:202,参数错误 203
				if (statusCode == 202) {
					handerRealDataResponse(LogicActions.NEED_TO_LOGIN, statusCode, content);
				} else if (statusCode == 200) {
					List<GatherData> realDatas = null;
					try {
						realDatas = new Gson().fromJson(content, new TypeToken<List<GatherData>>() {
						}.getType());
					} catch (Exception e) {
						e.printStackTrace();
					}
					if (realDatas != null) {
						List<CompositeData> compData = compositeData(realDatas);
						handerRealDataResponse(LogicActions.REAL_DATA_SUCCESS, statusCode, compData);
						warning(compData);
					} else {
						handerRealDataResponse(LogicActions.REAL_DATA_ERROR, statusCode, content);
					}
				} else {
					handerRealDataResponse(LogicActions.REAL_DATA_ERROR, statusCode, content);
				}
			}
		});
	}

	public void warning(List<CompositeData> realDatas) {
		if (realDatas == null) {
			return;
		}
		HashMap<String, SetAlarm> map = LoginLogic.getInstance().getSetAlarm();
		if (map == null || map.size() == 0) {
			return;
		}
		for (CompositeData compData : realDatas) {
			try {
				String devId = compData.getDeviceId();
				Device device = compData.getDeviece();
				String devName = device == null ? "" : device.getDeviceName();
				SetAlarm alarm = map.get(devId);
				GatherData gatherData = compData.getGatherData();
				float warnDust = -1f;
				float warnNoise = -1f;
				if (alarm != null) {
					warnDust = SetAlarmUtil.getWarnDust(alarm);
				}
				if (alarm != null) {
					warnNoise = SetAlarmUtil.getWarnNoise(alarm);
				}
				String dust = gatherData == null ? "-" : gatherData.getDustInst();
				String noise = gatherData == null ? "-" : gatherData.getLAFMaxPrf();
				if (!"-".equals(dust) && warnDust > -1 && Float.valueOf(dust) >= warnDust) {
					showDustNotify(devId, "粉尘警报", "设备" + devName + "当前粉尘浓度为:" + dust + "mg/m3", alarm.getDustDelay());
				} else if (!"-".equals(dust) && warnNoise > -1 && Float.valueOf(noise) >= warnNoise) {
					showNoiseNotify(devId, "噪声警报", "设备" + devName + "当前噪声值为：" + noise + "db", alarm.getNoiseDelay());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private Handler mHandler = new Handler(Looper.getMainLooper());
	private HashMap<String, WarningRunnable> runnableMap = new HashMap<String, WarningRunnable>();

	public class WarningRunnable implements Runnable {
		private long startTime;
		private String title;
		private String content;

		public void run() {
			App.app.showNotification(title, content);
		}

		public long getStartTime() {
			return startTime;
		}

		public void setStartTime(long startTime) {
			this.startTime = startTime;
		}

		public String getTitle() {
			return title;
		}

		public void setTitle(String title) {
			this.title = title;
		}

		public String getContent() {
			return content;
		}

		public void setContent(String content) {
			this.content = content;
		}

	}

	public void showDustNotify(String devId, final String title, final String content, final int delay) {
		WarningRunnable dustWarn = runnableMap.get(devId);
		if (dustWarn != null) {
			long startTime = dustWarn.getStartTime();
			if (System.currentTimeMillis() - startTime > delay * 60 * 1000) {
				dustWarn.setTitle(title);
				dustWarn.setContent(content);
				dustWarn.setStartTime(System.currentTimeMillis());
				mHandler.postDelayed(dustWarn, delay * 60 * 1000);
			}
		} else {
			dustWarn = new WarningRunnable();
			dustWarn.setTitle(title);
			dustWarn.setContent(content);
			dustWarn.setStartTime(System.currentTimeMillis());
			mHandler.post(dustWarn);
			runnableMap.put(devId, dustWarn);
		}

	}

	public void showNoiseNotify(String devId, final String title, final String content, final int delay) {

		WarningRunnable dustWarn = runnableMap.get(devId + "_noise");
		if (dustWarn != null) {
			long startTime = dustWarn.getStartTime();
			if (System.currentTimeMillis() - startTime > delay * 60 * 1000) {
				dustWarn.setTitle(title);
				dustWarn.setContent(content);
				dustWarn.setStartTime(System.currentTimeMillis());
				mHandler.postDelayed(dustWarn, delay * 60 * 1000);
			}
		} else {
			dustWarn = new WarningRunnable();
			dustWarn.setTitle(title);
			dustWarn.setContent(content);
			dustWarn.setStartTime(System.currentTimeMillis());
			mHandler.post(dustWarn);
			runnableMap.put(devId + "_noise", dustWarn);
		}
	}

	private List<CompositeData> compositeData(List<GatherData> realDatas) {
		gatherDataDao.deleteGatherData(true);
		gatherDataDao.insertGatherData(realDatas, true);
		List<Device> devices = deviceDao.getDevices();
		List<CompositeData> compositeDatas = new ArrayList<CompositeData>();
		for (Device device : devices) {
			String deviceId = device.getDeviceID();
			CompositeData data = new CompositeData();
			data.setDeviceId(deviceId);
			data.setDeviece(device);
			for (GatherData gatherData : realDatas) {
				if (deviceId.equals(gatherData.getDeviceID())) {
					data.setGatherData(gatherData);
					break;
				}
			}
			compositeDatas.add(data);
		}
		return compositeDatas;
	}

	public void getHistoryData(final OnHandlerResponse handler, String deviceId, long startTime, int dur) {
		ContentValues values = new ContentValues();
		values.put("devID", deviceId);
		values.put("startTime", startTime);
		values.put("dur", dur);
		httpUtil.get(HttpCommon.HISTORY_DATA + makeParamts(values), new StringHttpResponseListener() {

			@Override
			public void onFailure(int statusCode, String content, Throwable error) {
				// TODO Auto-generated method stub
				LogF.d(TAG, "getHistoryData statusCode:" + statusCode + ",content:" + content);
				handler.handlerResponse(LogicActions.HISTORY_DATA_ERROR, statusCode, content);
			}

			@Override
			public void onSuccess(int statusCode, String content) {
				LogF.d(TAG, "getHistoryData statusCode:" + statusCode + ",content:" + content);
				// 成功statusCode:200, 登录超时 statuscode:202,参数错误 203
				if (statusCode == 202) {
					handler.handlerResponse(LogicActions.NEED_TO_LOGIN, statusCode, content);
				} else if (statusCode == 200) {
					List<GatherData> historyDatas = null;
					try {
						historyDatas = new Gson().fromJson(content, new TypeToken<List<GatherData>>() {
						}.getType());
					} catch (Exception e) {
						// TODO: handle exception
					}
					if (historyDatas != null) {
						handler.handlerResponse(LogicActions.HISTORY_DATA_SUCCESS, statusCode, historyDatas);
					} else {
						handler.handlerResponse(LogicActions.HISTORY_DATA_ERROR, statusCode, content);
					}
				} else {
					handler.handlerResponse(LogicActions.HISTORY_DATA_ERROR, statusCode, content);
				}
			}
		});
	}

	public void getChart1(final OnHandlerResponse handler, long startTime) {
		ContentValues values = new ContentValues();
		values.put("reportTime", startTime);
		httpUtil.get(HttpCommon.REPORT1 + makeParamts(values), new StringHttpResponseListener() {
			public void onFailure(int statusCode, String content, Throwable error) {
				LogF.d(TAG, "getChart1 statusCode:" + statusCode + ",content:" + content);
				handler.handlerResponse(LogicActions.REPORT1_DATA_ERROR, statusCode, content);
			}

			public void onSuccess(int statusCode, String content) {
				LogF.d(TAG, "getChart1 statusCode:" + statusCode + ",content:" + content);
				if (statusCode == 202) {
					handler.handlerResponse(LogicActions.NEED_TO_LOGIN, statusCode, content);
					return;
				} else if (statusCode == 200) {
					List<Report1Data> historyDatas = new Gson().fromJson(content, new TypeToken<List<Report1Data>>() {
					}.getType());
					if (historyDatas != null) {
						handler.handlerResponse(LogicActions.REPORT1_DATA_SUCCESS, statusCode, historyDatas);
					} else {
						handler.handlerResponse(LogicActions.REPORT1_DATA_ERROR, statusCode, content);
					}
				} else {
					handler.handlerResponse(LogicActions.REPORT1_DATA_ERROR, statusCode, content);
				}
			}
		});
	}

	public void getChart2(final OnHandlerResponse handler, long startTime, int type) {
		ContentValues values = new ContentValues();
		values.put("reportTime", startTime);
		values.put("type", type);
		httpUtil.get(HttpCommon.REPORT2 + makeParamts(values), new StringHttpResponseListener() {

			public void onFailure(int statusCode, String content, Throwable error) {
				LogF.d(TAG, "getChart2 statusCode:" + statusCode + ",content:" + content);
				handler.handlerResponse(LogicActions.REPORT2_DATA_ERROR, statusCode, content);
			}

			public void onSuccess(int statusCode, String content) {
				LogF.d(TAG, "getChart2 statusCode:" + statusCode + ",content:" + content);
				if (statusCode == 202) {
					handler.handlerResponse(LogicActions.NEED_TO_LOGIN, statusCode, content);
					return;
				} else if (statusCode == 200) {
					List<Report2Data> historyDatas = new Gson().fromJson(content, new TypeToken<List<Report2Data>>() {
					}.getType());
					if (historyDatas != null) {
						handler.handlerResponse(LogicActions.REPORT2_DATA_SUCCESS, statusCode, historyDatas);
					} else {
						handler.handlerResponse(LogicActions.REPORT2_DATA_ERROR, statusCode, content);
					}
				} else {
					handler.handlerResponse(LogicActions.REPORT2_DATA_ERROR, statusCode, content);
				}
			}
		});
	}

	public void getChart3(final OnHandlerResponse handler, long startTime, int type) {
		ContentValues values = new ContentValues();
		values.put("reportTime", startTime);
		values.put("type", type);
		httpUtil.get(HttpCommon.REPORT3 + makeParamts(values), new StringHttpResponseListener() {

			public void onFailure(int statusCode, String content, Throwable error) {
				LogF.d(TAG, "getHistoryData statusCode:" + statusCode + ",content:" + content);
				handler.handlerResponse(LogicActions.REPORT3_DATA_ERROR, statusCode, content);
			}

			public void onSuccess(int statusCode, String content) {
				LogF.d(TAG, "getHistoryData statusCode:" + statusCode + ",content:" + content);
				// 成功statusCode:200, 登录超时 statuscode:202,参数错误 203
				if (statusCode == 202) {
					handler.handlerResponse(LogicActions.NEED_TO_LOGIN, statusCode, content);
					return;
				} else if (statusCode == 200) {
					List<Report3Data> historyDatas = new Gson().fromJson(content, new TypeToken<List<Report3Data>>() {
					}.getType());
					if (historyDatas != null) {
						handler.handlerResponse(LogicActions.REPORT3_DATA_SUCCESS, statusCode, historyDatas);
					} else {
						handler.handlerResponse(LogicActions.REPORT3_DATA_ERROR, statusCode, content);
					}
				} else {
					handler.handlerResponse(LogicActions.REPORT3_DATA_ERROR, statusCode, content);
				}
			}
		});
	}

}
